// #include <iostream>
// #include <pthread.h>
// #include <string>
// #include <vector>
// #include <unistd.h>
// using namespace std;
// class threadData
// {
// public:
//     threadData(int number)
//     {
//         name = "thread-" + to_string(number);
//     }
//     string name;
// };
// int tickets = 100;
// void *getTicket(void *args)
// {
//     threadData *td = static_cast<threadData *>(args); // 原本因通用传参变成 void* 的 args，转换回实际的 threadData 指针
//     const char *name = td->name.c_str();
//     while (1)
//     {
//         if (tickets > 0)
//         {
//             usleep(1000);
//             printf("who=%s,get a ticket:%d\n", name, tickets);
//             tickets--;
//         }
//         else
//         {
//             break;
//         }
//     }
//     return nullptr;
// }
// const int NUM = 4;
// int main()
// {
//     vector<pthread_t> tids;
//     vector<threadData*> thread_datas;
//     for (int i = 1; i <= NUM; i++)
//     {
//         pthread_t tid;
//         threadData *td = new threadData(i);
//         thread_datas.emplace_back(td);
//         pthread_create(&tid, nullptr, getTicket, thread_datas[i - 1]);
//         tids.emplace_back(tid);
//     }
//     for (auto thread : tids)
//     {
//         pthread_join(thread, nullptr);
//     }
//     for (auto td : thread_datas)
//     {
//         delete td;
//     }
//     return 0;
// }

#include <iostream>
#include <pthread.h>
#include <string>
#include <vector>
#include <unistd.h>
using namespace std;
class threadData
{
public:
    threadData(int number)
    {
        name = "thread-" + to_string(number);
    }
    string name;
};
pthread_mutex_t mutex;
int tickets = 1000;
void *getTicket(void *args)
{
    threadData *td = static_cast<threadData *>(args); // 原本因通用传参变成 void* 的 args，转换回实际的 threadData 指针
    const char *name = td->name.c_str();
    while (1)
    {
        pthread_mutex_lock(&mutex);
        if (tickets > 0)
        {
            usleep(10000);
            printf("who=%s,get a ticket:%d\n", name, tickets);
            tickets--;
            pthread_mutex_unlock(&mutex);
            usleep(10000);
        }
        else
        {
            pthread_mutex_unlock(&mutex);
            break;
        }
    }
    return nullptr;
}
const int NUM = 4;
int main()
{
    vector<pthread_t> tids;
    vector<threadData*> thread_datas;
    pthread_mutex_init(&mutex, NULL);
    for (int i = 1; i <= NUM; i++)
    {
        pthread_t tid;
        threadData *td = new threadData(i);
        thread_datas.emplace_back(td);
        pthread_create(&tid, nullptr, getTicket, thread_datas[i - 1]);
        tids.emplace_back(tid);
    }
    for (auto thread : tids)
    {
        pthread_join(thread, nullptr);
    }
    for (auto td : thread_datas)
    {
        delete td;
    }
    pthread_mutex_destroy(&mutex);
    return 0;
}